package com.ofek.eventos.db;

import java.util.ArrayList;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.content.LocalBroadcastManager;

import com.ofek.db.Table;
import com.ofek.eventos.Constants;
import com.ofek.eventos.EventosApplication;
import com.ofek.eventos.db.datatypes.predefined.BuyListContext;
import com.ofek.eventos.db.datatypes.predefined.BuyListPage;
import com.ofek.eventos.db.datatypes.predefined.ContextDefiner;
import com.ofek.eventos.db.datatypes.predefined.DiaryContext;
import com.ofek.eventos.db.datatypes.predefined.NextWeekPage;
import com.ofek.eventos.db.datatypes.predefined.PageDefiner;
import com.ofek.eventos.db.datatypes.predefined.ThisWeekPage;
import com.ofek.eventos.db.datatypes.predefined.TodayPage;
import com.ofek.eventos.db.datatypes.predefined.TommorowPage;

public class ContextDatabase {
	public static final String CONTEXT_REMOVE_REQUEST = "CONTEXT_REMOVE_REQUEST";
	public static final String CONTEXT_EXTRA = "CONTEXT_EXTRA";
	private final SQLiteDatabase db;
	private final Table<ContextWrapper> ctxTable;
	private final Table<PageWrapper> pageTable;
	private final Table<PageInContext> pagesInCtxTable;





	private static ContextDatabase instance;

	@SuppressWarnings("unchecked")
	private ContextDatabase() {
		final Context context = EventosApplication.context;
		LocalBroadcastManager.getInstance(context).registerReceiver(new BroadcastReceiver() {
			/* (non-Javadoc)
			 * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
			 */
			@Override
			public void onReceive(final Context context, final Intent intent) {
				final ContextWrapper event = (ContextWrapper) intent.getSerializableExtra(CONTEXT_EXTRA);
				remove(event);
			}
		}, new IntentFilter(CONTEXT_REMOVE_REQUEST));
		db = SQLiteDatabase.openDatabase(Constants.EVENTOS_CONTEXT_DB_FILE.getPath() , null, SQLiteDatabase.CREATE_IF_NECESSARY);
		db.execSQL("PRAGMA foreign_keys=ON;");
		ctxTable = new Table<ContextWrapper>(ContextWrapper.class);
		ctxTable.create(db);
		pageTable = new Table<PageWrapper>(PageWrapper.class); 
		pageTable.create(db);
		pagesInCtxTable = new Table<PageInContext>(PageInContext.class);
		pagesInCtxTable.create(db);
		if (ctxTable.size()!=0) return;
		ContextWrapper diaryContext = new DiaryContext();
		diaryContext = add(diaryContext);
		add(diaryContext,new TodayPage());
		add(diaryContext,new TommorowPage());
		add(diaryContext,new ThisWeekPage());
		add(diaryContext,new NextWeekPage());
		ctxTable.insertIfNotExists(diaryContext);
		ContextWrapper buyListContext = new BuyListContext();
		buyListContext = add(buyListContext);
		add(buyListContext,new BuyListPage());
		ctxTable.insertIfNotExists(buyListContext);
	}
	/**
	 * @param contextWrapper
	 * @param newPageDefiner
	 * @return 
	 */
	public PageWrapper add(final ContextWrapper contextWrapper, final PageDefiner newPageDefiner) {
		final PageWrapper p=new PageWrapper(newPageDefiner);
		p.id = pageTable.add(p);
		pagesInCtxTable.update(new PageInContext(contextWrapper.id,p.id));
		sync();
		return p;
	}
	public ContextWrapper add(final ContextDefiner context) {
		final ContextWrapper wrap = new ContextWrapper(context);
		wrap.id = ctxTable.add(wrap);
		sync();
		return wrap;
	}
	/**
	 * @param contextWrapper
	 * @param newPageDefiner
	 */
	public void addOrUpdate(final ContextWrapper contextWrapper,final PageWrapper p) {
		final long id = pageTable.update(p);
		p.id = id == -1 ? p.id : id;
		pagesInCtxTable.update(new PageInContext(contextWrapper.id,p.id));
		sync();
	}



	/**
	 * @param contextWrapper
	 * @param object
	 */
	public void remove(final ContextWrapper contextWrapper, final PageWrapper object) {
		pageTable.remove(object);
	}



	/**
	 * @param contextWrapper
	 * @return
	 */
	public ArrayList<PageWrapper> getAll(final ContextWrapper contextWrapper) {
		final ArrayList<PageInContext> all = pagesInCtxTable.getAll("cid="+contextWrapper.id);
		final ArrayList<PageWrapper> result = new ArrayList<PageWrapper>();
		for (final PageInContext p : all) 
			result.add(pageTable.get("id="+p.pid));
		return result;
	}


	/**
	 * @param contextWrapper
	 */
	public void clear(final ContextWrapper contextWrapper) {
		final ArrayList<PageWrapper> all = getAll(contextWrapper);
		for (final PageWrapper p : all) pageTable.remove(p);
	}




	public static ContextDatabase getInstance() {
		if (instance == null) {
			instance = new ContextDatabase();
			System.out.println("RECREATED CONTEXT DABASE!");
		}
		return instance;
	}

	public void sync() {
		LocalBroadcastManager.getInstance(EventosApplication.context).sendBroadcast(new Intent(Constants.EVENT_NOTIFY_EVENT_SET_CHANGED));
	}

	public ArrayList<ContextWrapper> getAll() {
		return ctxTable.getAll();
	}


	public void remove(final ContextWrapper ctxDef) {
		ctxTable.remove(ctxDef);
		sync();
	}
	/**
	 * @param contextWrapper
	 * @return
	 */
	public ContextWrapper getParent(final ContextWrapper contextWrapper) {
		return null;
	}
	/**
	 * @param pageWrapper
	 * @return
	 */
	public ContextWrapper getParent(final PageWrapper pageWrapper) {
		return ctxTable.get("id="+pagesInCtxTable.get("pid="+pageWrapper.id).cid);
	}


}
